package org.heart.controller;


import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.heart.common.CommonResult;
//import org.heart.controller.excel.ExcelParserService;
import org.heart.thirdService.AIServiceAPI.service.AisServices;
import org.heart.thirdService.AIServiceAPI.tools.WeatherTool;
import org.heart.thirdService.hefengAPI.req.Location;
import org.heart.thirdService.hefengAPI.req.NowWeather;
import org.heart.thirdService.hefengAPI.service.HeFengApiServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;

import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_3_5_TURBO;

@RequestMapping("/api")
@RestController
public class TestController {

    private static final Logger log = LoggerFactory.getLogger(TestController.class);
    @Resource
    private HeFengApiServiceImpl heFengApiService;

//    @Autowired
//    private ExcelParserService excelParserService;

//    @Resource
//    public AiService aiServices;

    @Resource
    private OpenAiChatModel openAiChatModel;

    @GetMapping("/queryState")
    public CommonResult<String> queryState() {

        log.info("请求接口 '/api/test'");

        return CommonResult.successResponse("健康实例！");
    }


//    @PostMapping("/uploadExcel")
//    public Map<String, Object> uploadExcel(@RequestParam("file") MultipartFile file) throws IOException {
//        Map<String, Object> result = new HashMap<>();
//        List<List<String>> data = new ArrayList<>();
//        List<Map<String, Object>> merges = new ArrayList<>();
//        Map<String, Map<String, String>> stylesMap = new HashMap<>();
//
//        InputStream in = file.getInputStream();
//        Workbook workbook = WorkbookFactory.create(in);  // EasyPOI 基于 POI 封装，兼容 WorkbookFactory
//        Sheet sheet = workbook.getSheetAt(0);
//        DataFormatter formatter = new DataFormatter();
//
//        int maxRow = sheet.getLastRowNum();
//        int maxCol = 0;
//        for (int i = 0; i <= maxRow; i++) {
//            Row row = sheet.getRow(i);
//            if (row != null) {
//                maxCol = Math.max(maxCol, row.getLastCellNum());
//            }
//        }
//
//        for (int r = 0; r <= maxRow; r++) {
//            Row row = sheet.getRow(r);
//            List<String> rowData = new ArrayList<>();
//            boolean isRowEmpty = true;
//            for (int c = 0; c < maxCol; c++) {
//                Cell cell = row != null ? row.getCell(c, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK) : null;
//                String val = "";
//
//                if (cell != null) {
//                    if (cell.getCellType() != CellType.BLANK) {
//                        val = getFormattedCellValue(cell); // 自动处理日期格式问题
//                        if (!val.trim().isEmpty()) {
//                            isRowEmpty = false;
//                        }
//                    }
//
//                    CellStyle style = cell.getCellStyle();
//                    if (style != null) {
//                        StringBuilder cls = new StringBuilder();
//
//                        if (hasBorder(style)) {
//                            if (style.getBorderTop() != BorderStyle.NONE) cls.append(" border-top");
//                            if (style.getBorderBottom() != BorderStyle.NONE) cls.append(" border-bottom");
//                            if (style.getBorderLeft() != BorderStyle.NONE) cls.append(" border-left");
//                            if (style.getBorderRight() != BorderStyle.NONE) cls.append(" border-right");
//                        }
//
//                        if (style.getAlignment() == HorizontalAlignment.CENTER) cls.append(" align-center");
//                        else if (style.getAlignment() == HorizontalAlignment.LEFT) cls.append(" align-left");
//                        else if (style.getAlignment() == HorizontalAlignment.RIGHT) cls.append(" align-right");
//
//                        if (style.getVerticalAlignment() == VerticalAlignment.CENTER) cls.append(" valign-middle");
//
//                        Font font = workbook.getFontAt(style.getFontIndexAsInt());
//                        if (font != null && font.getBold()) cls.append(" font-bold");
//                        cls.append(" font-").append(font.getFontHeightInPoints());
//
//                        Map<String, String> m = new HashMap<>();
//                        m.put("className", cls.toString().trim());
//                        stylesMap.put(r + "-" + c, m);
//                    }
//                }
//
//                rowData.add(val);
//            }
//            if (!isRowEmpty) {
//                data.add(rowData);
//            }
////            data.add(rowData);
//        }
//
//        // 合并单元格信息
//        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
//            CellRangeAddress range = sheet.getMergedRegion(i);
//            Map<String, Object> merge = new HashMap<>();
//            merge.put("row", range.getFirstRow());
//            merge.put("col", range.getFirstColumn());
//            merge.put("rowspan", range.getLastRow() - range.getFirstRow() + 1);
//            merge.put("colspan", range.getLastColumn() - range.getFirstColumn() + 1);
//            merges.add(merge);
//
//            // 填补合并边框
//            for (int r = range.getFirstRow(); r <= range.getLastRow(); r++) {
//                for (int c = range.getFirstColumn(); c <= range.getLastColumn(); c++) {
//                    String key = r + "-" + c;
//                    Map<String, String> style = stylesMap.getOrDefault(key, new HashMap<>());
//                    String cls = style.getOrDefault("className", "");
//                    Set<String> clsSet = new HashSet<>(Arrays.asList(cls.split("\\s+")));
//                    if (r == range.getFirstRow()) clsSet.add("border-top");
//                    if (r == range.getLastRow()) clsSet.add("border-bottom");
//                    if (c == range.getFirstColumn()) clsSet.add("border-left");
//                    if (c == range.getLastColumn()) clsSet.add("border-right");
//                    style.put("className", String.join(" ", clsSet));
//                    stylesMap.put(key, style);
//                }
//            }
//        }
//
//        result.put("data", data);
//        result.put("merges", merges);
//        result.put("styles", stylesMap);
//        return result;
//    }

//    private String getFormattedCellValue(Cell cell) {
//        DataFormatter formatter = new DataFormatter();
//        String value = formatter.formatCellValue(cell);
//        if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
//            try {
//                Date date = cell.getDateCellValue();
//                return new SimpleDateFormat("yyyy-MM-dd").format(date);
//            } catch (Exception e) {
//                return value;
//            }
//        }
//        return value;
//    }

//    private boolean hasBorder(CellStyle style) {
//        return style.getBorderTop() != BorderStyle.NONE ||
//                style.getBorderBottom() != BorderStyle.NONE ||
//                style.getBorderLeft() != BorderStyle.NONE ||
//                style.getBorderRight() != BorderStyle.NONE;
//    }


    /**
     * 测试
     */
    @GetMapping("/test")
    public CommonResult<Object> test() {

        log.info("请求接口 '/api/test'");

        NowWeather nowWeather = heFengApiService.getNowWeather("101010100");

        return CommonResult.successResponse(nowWeather);
    }


    @GetMapping("/textAi")
    public String testAi() {

        System.out.println("textAi");
        String message = "";

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AisServices assistant = dev.langchain4j.service.AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .chatMemory(chatMemory)
                .tools(new WeatherTool())
                .build();

        try {
            message = assistant.chat1("今天的南阳天气怎么样");
            System.out.println(message);
//            /**
//             * 获取今日温馨一言
//             */
//            message = assistant.getAWarmWord("阴雨天气");
//            System.out.println("获取今日温馨一言: " + message);
//            /**
//             * 获取基于天气类型的健康建议
//             */
//            message = assistant.getHealthAdvice("阴雨天气");
//            System.out.println("获取基于天气类型的健康建议: " + message);
//
//            message = assistant.getWarmReminder("阴雨天气");
//            System.out.println("获取温馨提醒: " + message);
        } catch (Exception e) {
            System.out.println(e);
        }
        return message;
    }

    @GetMapping("/getStream")
    public void getStream() {

        StreamingChatModel model = OpenAiStreamingChatModel.builder()
                .apiKey("sk-V4iVhzUk3TXnTDUlwHtzOg4Lu3SDuBldiaQMXhM4GXicBv4Z")
                /**
                 * GPT 模型
                 */
                .modelName(GPT_3_5_TURBO)
                /**
                 * 介于 -2.0 和 2.0 之间的数字。
                 * 正值会根据新标记到目前为止在文本中的现有频率来惩罚新标记，从而降低模型逐字重复同一行的可能性。
                 */
                .frequencyPenalty(1.0)
                /**
                 * 记录请求
                 */
                .logRequests(true)
                /**
                 * 记录响应
                 */
                .logResponses(true)
                .baseUrl("https://sg.uiuiapi.com/v1")
                .build();

        String userMessage = "给我讲一个笑话";

        model.chat(userMessage, new StreamingChatResponseHandler() {

            @Override
            public void onPartialResponse(String partialResponse) {
                System.out.println("onPartialResponse: " + partialResponse);
            }

            @Override
            public void onCompleteResponse(ChatResponse completeResponse) {
                System.out.println("onCompleteResponse: " + completeResponse);
            }

            @Override
            public void onError(Throwable error) {
                error.printStackTrace();
            }
        });

    }


    @GetMapping("getCityInfo")
    public Location getCityInfo() {

        Location location = heFengApiService.getLocation("112.56", "32.96");

        return location;
    }


    /**
     * 集成 RAG 系统
     *
     * 从文件系统中 读取文件信息
     */
    @GetMapping("/testRag")
    public CommonResult<String> integrationRag(@RequestParam("city") String city) {

        String projectRootPath = new File("").getAbsolutePath();
        String filePath = projectRootPath + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "static";

        List<Document> documents = FileSystemDocumentLoader.loadDocuments(filePath);
        InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        System.out.println("embeddingStore=="+embeddingStore);

        EmbeddingStoreIngestor.ingest(documents, embeddingStore);

        System.out.println("embeddingStore=="+embeddingStore);

        AisServices assistant = AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore))
                .build();


        String message = assistant.chat1(
                "请从数据中精确查询 `location_name_zh` 字段值为 '" + city + "' 的城市记录，并返回以下信息：\n"
                        + "location_id 值,"
        );
        return CommonResult.successResponse(message);
    }

    public static void main(String[] args) {
        String projectRootPath = new File("").getAbsolutePath();

        String filePath = projectRootPath + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "static" + File.separator + "cityCodeList.xls";

        System.out.println(filePath);

    }
}
